package com.game.commons.network;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * 接受器，接受套接字连接
 * @author 杜祥
 * @create 2013-6-3
 */
public class Acceptor 
{
	
	/**
	 * 连接创建工厂
	 */
	private final ConnectionFactory cf;
	
	/**
	 * NIO服务
	 */
	private final NioServer server;
	
	
	
	/**
	 * 构造一个新的接受器，并设置连接创建工厂和Nio服务
	 * @param cf
	 * @param server
	 * @see com.game.commons.network.ConnectionFactory
	 * @see com.game.commons.network.NioServer
	 */
	public Acceptor(ConnectionFactory cf, NioServer server)
	{
		this.cf = cf;
		
		this.server = server;
	}
	
	
	/**
	 * 有新连接连接时，由调度器调用此方法。
	 * @param key
	 * @throws IOException
	 * @see java.nio.channels.ServerSocketChannel
	 * @see java.nio.channels.SelectionKey
	 * @see java.nio.channels.SocketChannel
	 * @see java.nio.channels.Selector
	 * @see com.game.commons.network.Dispatcher
	 * @see com.game.commons.network.MMOConnection
	 * @see com.game.commons.network.ConnectionFactory 
	 */
	public final void accept(SelectionKey key) throws IOException
	{
		ServerSocketChannel socket = (ServerSocketChannel)key.channel();
		SocketChannel socketChannel = socket.accept();
		socketChannel.configureBlocking(Boolean.FALSE);
		
		Dispatcher dispatcher = server.getReadWriteDispatcher();
		MMOConnection con = cf.create(socketChannel, dispatcher);
		
		if(con == null)
			return ;
		
		dispatcher.register(socketChannel, SelectionKey.OP_READ, con);
		
		con.initialized();
	}
}
